// index.js
// 获取应用实例，主要用来存需要共享的座位号
const app = getApp()
//主要用于引入计算属性
const computedBehavior = require('miniprogram-computed').behavior
//引入访问后端api
const api = require("../../api/index.js")

Component({
  //引入计算属性
  behaviors: [computedBehavior],

  data: {
    logo:"https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/5d20923d-1210-42ef-a944-12d4fee402a8.png",
    baseList:["https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/b4144595-ef47-4d7f-a55e-fdaf4f98f50a.png","https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/942e047e-f0f5-4138-b7e8-2e41486cc6e2.png","https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/7fc1a521-a04a-41fa-9e04-5796bfe73375.png","https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/1c984620-2c33-44f4-8fb4-5a35bd1c5fe3.png","https://mis-western-restaurant.oss-cn-guangzhou.aliyuncs.com/images/2022/04/22/2b9d9e73-6c70-48cf-8486-6df5f7f83867.png"],
    //在最底下占两个空位安卓滑到最小也可以
    ocupy: 2,
    //头部状态栏的高度
    statusBarHeight: wx.getSystemInfoSync().statusBarHeight,
    //搜索框双向
    searchvalue: "",
    //如果为true则三个menu都会wx:if消失掉
    searchorno: false,
    //那个加入购物车动画提取图片，会根据点的图片改变
    throwimg: "",
    //最大的这个div能不能滚动
    bigscroll: false,
    //最大的div滚动的top
    bigtop: "",
    //主要是zhezhao那个黑色的zhezhao要不要show,还有就是那个浮动购物车条点击时如果这个是true则调用hiddcar()
    carcontentshow: false,
    //leftmenu也就是左类栏白色的是哪个
    whiteIndex: 0,
    //主要是左栏如果太长，这个让它自动往下滚
    leftmenutop: 0,
    //主要是搜索栏那里针对ios和安卓进行适配，这个是检测当前设备是什么
    _system: "ios",
    //左菜单
    leftmenu: [],
    //右菜单
    rightmenu: [],
  },
  created() {
      
    //一开始就拿菜单
    this.getMenu()
    //一般是点击加号后记录加号左上角位置也就是靠近图片位置
    this._throwlocation = ""
  },
  ready() {
    //一开始就让你选座
    this.selectComponent(".seat").show("/user/chooseTable")
    //初始化头部动画
    this._animate()
    //把需要节流的地方都节流
    this.debouce_addmany = this.throttle(this.debouce_addmany, 1000)
    this.addmany_simple = this.throttle(this.addmany_simple, 1000)
    this.jianmany = this.throttle(this.jianmany, 1000)
    this.scrollthing = this.throttle(this.scrollthing, 130)
    
  },

  //computed触发条件的关键在于有关键字变化了比如data.rightmenu[i].child[j].num
  computed: {
    //匹配搜索名字的item组成searchmenu返回，查询效率很低就是，用的是遍历
    searchmenu(data) {
      let arr = []
      for (let i = 0; i < data.rightmenu.length; i++) {
        for (let j = 0; j < data.rightmenu[i].child.length; j++) {
          if (data.searchvalue != "" && (data.rightmenu[i].child[j].itemName.indexOf(data.searchvalue) != -1) && data.rightmenu[i].child[j].num < 1000) {
            arr.push(data.rightmenu[i].child[j])
          }
        }
      }
      return arr
    },
    //遍历item数量不为0的推荐购物车数组
    carthing(data) {
      let cararr = []
      for (let i = 0; i < data.rightmenu.length; i++) {
        for (let j = 0; j < data.rightmenu[i].child.length; j++) {
          if (data.rightmenu[i].child[j].num != 0) {
            if (data.rightmenu[i].child[j].guige === false && data.rightmenu[i].child[j].combo === false) {
              cararr.push(data.rightmenu[i].child[j])
            } else {
              data.rightmenu[i].child[j].kids.map(item => {
                if (item.num > 0) cararr.push(item)
              })

            }
          }
        }
      }
      return cararr
    },
    //计算总件数
    thingnum(data) {
      let sum = 0
      data.carthing.forEach((e) => {
        sum = sum + e.num
      })
      return sum
    },
    //计算总价
    totalmoney(data) {
      let sum = 0
      data.carthing.forEach((e) => {
        sum = sum + e.num * e.price
      })
      if (sum === 0) return "未选购商品"
      else return "￥" + sum.toFixed(2)
    }
  },

  //监视如果购物车没东西则弹出框消失
  observers: {
    'thingnum': function (thingnum) {
      if (thingnum == 0) this.hiddcar()
    },
  },




  methods: {
    refresh() {
      wx.showLoading({
        title: '刷新菜单中',
      })
      this.setData({
        leftmenu:[],
        rightmenu:[]
      })
      this.getMenu();
    },
    //拿到左右菜单并计算属性
    getMenu() {
      let r = new Promise((resolve, reject) => {
        api.rightmenu({
          success: (res) => {
            res.data.data.rightmenu.map((item) => {
              item.child.map((i) => {
                //把后端没传过来但我们需要的属性加上去
                i.num = 0
                i.kids = []
              })
            })
            //两个占位的
            for (let i = 0; i < this.data.ocupy; i++) {
              res.data.data.rightmenu.push({
                categoryName: "",
                categoryNo: i + "5210",
                child: []
              })
            }
            //添加右菜单
            this.setData({
              rightmenu: res.data.data.rightmenu,
            })
            resolve()
          },
          //失败自动刷新
          fail: () => {
            setTimeout(() => {
              this.getMenu()
            }, 1000)
          }
        })
      })
      let l= new Promise((resolve, reject) => {
          api.leftmenu({
            //两个占位
            success: (res) => {
              for (let i = 0; i < this.data.ocupy; i++) {
                res.data.data.leftmenu.push({})
              }
              
              this.setData({
                leftmenu: res.data.data.leftmenu,
              })
              resolve()
            },
            //如果失败则重新获取
            fail: (res) => {
              setTimeout(() => {
                this.getMenu()
              }, 1000)
            }
          })
      })
      Promise.all([r,l]).then(()=>{
            this.calculateTop()
      })
    },

    //开始时计算每个右菜单类的top给左菜单属性赋值top,当点击左菜单时可以把bigtop设为该item的top即为右菜单的top
    calculateTop() {
      let query = wx.createSelectorQuery().in(this)
      for (let i = 0; i < this.data.leftmenu.length; i++) {
        let id = "#A" + this.data.rightmenu[i].categoryNo
        query.select(id).boundingClientRect((res) => {
          if (res===null) {
            return
          }
          
          this.setData({
            //因为我为了动画把一开始的坐标就弄得很离谱它就开始计算了，现在是等它稳定再开始算
            [`leftmenu[${i}].top`]: res.top - 140
          })
        })
        if(i===this.data.leftmenu.length-1){
          wx.hideLoading()
        }
      }
      query.exec()
    },

    // 系列动画
    // 头部动画
    _animate() {
      wx.createSelectorQuery().select('#scroller').fields({
        scrollOffset: true,
        size: true,
      }, (res) => {
        this.animate('.avatar', [{
          borderRadius: '20%',
          borderColor: '#13227a',
          transform: 'scale(1) translateY(-20px)',
          offset: 0,
        }, {
          borderRadius: '30%',
          borderColor: '#13227a',
          transform: 'scale(.65) translateY(-40px)',
          offset: .5,
        }, {
          borderRadius: '50%',
          borderColor: 'blue',
          transform: `scale(.34) translateY(-80px) translateX(10px)`,
          offset: 1
        }], 2000, {
          scrollSource: '#scroller',
          timeRange: 2000,
          startScrollOffset: 0,
          endScrollOffset: 85,
        })

        this.animate('.shopname', [{
          transform: 'translateY(0)',
        }, {
          transform: `translateY(${-84 - this.data.statusBarHeight}px)`,
        }], 1000, {
          scrollSource: '#scroller',
          timeRange: 1000,
          startScrollOffset: 120,
          endScrollOffset: 200,
        })
        this.animate('.search_bar', [{
          opacity: '0',
        }, {
          opacity: '1',
        }], 1000, {
          scrollSource: '#scroller',
          timeRange: 1000,
          startScrollOffset: 100,
          endScrollOffset: 200
        })
        this.animate('.search_input', [{
          opacity: '0',
          
        }, {
          opacity: '1',
         
        }], 1000, {
          scrollSource: '#scroller',
          timeRange: 1000,
          startScrollOffset: 100,
          endScrollOffset: 200
        })

      }).exec()

    },
    //三个菜单初次入场和搜索结束入场，记住这里的初始动画是真的会闪现到那个位置
    threeinanimation() {
      this.animate("#menu", [{
          translateY: -200,
          opacity: "0",
        },
        {
          translateY: 0,
          opacity: "1"
        },
      ], 300)
      this.animate(".leftmenu", [{
          top: "880px",
          opacity: "0",
        },
        {
          top: "150px",
          opacity: "1"
        },
      ], 300)
      this.animate(".rightmenu", [{
          translateY: 150,
          opacity: "0"
        },
        {
          translateY: 0,
          opacity: "1"
        }
      ], 300)
    },
    /*搜索系列方法*/
    //搜索动画，最复杂的地方
    searchanimation() {
      //有些手机会卡一下，针对不同系统优化
      //放前面searchValue先没有
      wx.getSystemInfo({
        success: (res) => {
          console.log(res)
          this.setData({
            _system: res.system,
            searchvalue: ""
          })
        }
      })
      if (this.data.searchorno === false) {
        if (this.data._system.indexOf("O") != -1){
          this.animate(".leftmenu", [{
            top: "150px",
            opacity: "1"
          },
          {
            top: "880px",
            opacity: "0"
          },
        ], 300)
        this.animate(".rightmenu", [{
            translateY: 0,
            opacity: "1"
          },
          {
            translateY: 150,
            opacity: "0"
          },
        ], 300)
        this.animate("#menu", [{
            translateY: 0,
            opacity: "1"
          },
          {
            translateY: -150,
            opacity: "0"
          },
        ], 300)
          setTimeout(() => {
            this.setData({
              searchorno: true,
            }, () => {
              this.setData({
                bigtop: "500px",
              }, () => {
                this.animate(".searchcontent", [{
                  opacity: 0
                }, {
                  opacity: 1
                }], 300, () => {
                  this.setData({
                    bigscroll: false
                  })
                })
              })
            })

          }, 400)
      } else {
        this.setData({
          bigtop: "1050px",
          searchorno: true,
        }, () => {
          this.animate(".searchcontent", [{
            opacity: 0
          }, {
            opacity: 1
          }], 1, () => {
            this.setData({
              bigscroll: false,
              bigtop: "1050px",
            })
            this.animate(".leftmenu", [{
              opacity: "1"
            },
            {
              opacity: "0"
            },
          ], 1)
          this.animate(".rightmenu", [{
    
              opacity: "1"
            },
            {
    
              opacity: "0"
            },
          ], 1,()=>{
            this.setData({
              bigtop: "1050px",
            })
          })
          this.animate("#menu", [{
    
              opacity: "1"
            },
            {
    
              opacity: "0"
            },
          ], 1)
          })
          this.setData({
            bigtop: "1050px",
          })
        })
      }
    }
    },
    //退出搜索，其实就一个入场动画  
    searchOut() {
      if (this.data.searchorno === true) {
        this.setData({
          searchorno: false,
          bigscroll: true,
          searchvalue: ""
        })
        this.threeinanimation()
      }
    },

    //规格系列
    //选规格，把组件调用出来还好设好照片等东西
    chooseGuiGe(e) {
      this.selectComponent(".guige").show(e.currentTarget.dataset.item)
      // 先设定好投入进购物车的动画位置和照片
      this._throwlocation = {
        y: e.detail.y - 80,
        x: e.detail.x - 270
      }
      this.setData({
        throwimg: e.currentTarget.dataset.item.photoUrl,
      })
    },
    //改变规格
    changeguige(e) {
      // 改变规格的这个Item拥有改变规格所需要的一切信息
      let TargetItem = e.currentTarget.dataset.item
      //让购物车消失，否则就会出现购物车出现先加后减的情况
      this.hiddcar()
      this.selectComponent(".guige").change(TargetItem.parentItem, TargetItem)
      // 把这个修改的东西的件数保留起来，等会就算保存的相当于也用了加的接口，所以要把原来的减掉，加完（改完）以后减，然后显示购物车
      this.call = () => {
        const name = `rightmenu[${(TargetItem.grandparentKey)}].child[${TargetItem.parentKey}].kids[${TargetItem.key}].num`
        const fname = `rightmenu[${(TargetItem.grandparentKey)}].child[${TargetItem.parentKey}].num`
        let num = TargetItem.num
        this.setData({
          [name]: this.data.rightmenu[(TargetItem.grandparentKey)].child[TargetItem.parentKey].kids[TargetItem.key].num - num,
          [fname]: this.data.rightmenu[(TargetItem.grandparentKey)].child[TargetItem.parentKey].num - TargetItem.num
        })
        this.showcar()
      }
    },
    //增加完以后就抛物动画
    onguige_animate(e) {
      this.throw()
      setTimeout(() => {
        this.onguige(e)
      }, 400)
    },
    //特别注意不管是简单的加还是改（先加后减)都会用到加，
    onguige(guigeItem) {
      //由guige组装起来的规格对象组成，里面有规格需要的数据
      const i = guigeItem.detail
      //是itemNo的那个Item，通过它可以在Kids里的某个Item找到所选的选项组合
      const iItem = i.item
      //如果原已经加了这种选项的规格，那么加num就好了否则就要Push,一定要记得加父亲，老是忘记
      if (!this.data.rightmenu[(iItem.parentKey)].child[iItem.key].kids.some(item => {
          if (item.descir === i.descir) {
            let name = `rightmenu[${(iItem.parentKey)}].child[${iItem.key}].kids[${item.key}].num`
            const fname = `rightmenu[${(iItem.parentKey)}].child[${iItem.key}].num`
            this.setData({
              [name]: item.num + i.num,
              [fname]: this.data.rightmenu[(iItem.parentKey)].child[iItem.key].num + i.num
            })
            return true
          }
          return false
        })) {
        const name = `rightmenu[${(iItem.parentKey)}].child[${iItem.key}].kids`
        const bignum = `rightmenu[${(iItem.parentKey)}].child[${iItem.key}].num`
        //kid才是真正放进购物车的Item
        let kid = {
          guige: iItem.guige,
          combo: iItem.combo,
          itemName: iItem.itemName,
          itemNo: iItem.itemNo,
          grandparentKey: iItem.parentKey,
          key: this.data.rightmenu[(iItem.parentKey)].child[iItem.key].kids.length,
          price: i.price,
          num: i.num,
          descir: i.descir,
          photoUrl: iItem.photoUrl,
          parentKey: iItem.key,
          //存起来在那个修改时可以用
          parentItem: iItem
        }
        this.data.rightmenu[(iItem.parentKey)].child[iItem.key].kids.push(kid)
        let add = this.data.rightmenu[(iItem.parentKey)].child[iItem.key].kids
        this.setData({
          [name]: add,
          [bignum]: this.data.rightmenu[(iItem.parentKey)].child[iItem.key].num + i.num
        })
      }
      //上面都是加
      //下面把原来的删掉
      if (i.change) {
        //在changeguige()那里创建的
        this.call()
      }
    },


    /*加减系列方法*/
    //下面加减购物车共享部分
    addreduceShare({
      e,
      method,
      callBack
    }) {
      const num = e.currentTarget.dataset.item.num
      const name = `rightmenu[${(e.currentTarget.dataset.item.parentKey)}].child[${e.currentTarget.dataset.item.key}].num`
      let fdes
      if ((!e.currentTarget.dataset.item.descir) || e.currentTarget.dataset.item.descir.indexOf("+") == -1) {
        fdes = (e.currentTarget.dataset.item.descir || '') + "+"
      }
      api.dofood({
        data: {
          itemNo: e.currentTarget.dataset.item.itemNo,
          method: method,
          num: 1,
          detail: fdes
        },
        success: (res) => {

          callBack(res, name, num)
        }
      })
    },
    //前端规格套餐部分加减
    doComboOrGuige(method, e) {
      const num = e.currentTarget.dataset.item.num
      const name = `rightmenu[${(e.currentTarget.dataset.item.grandparentKey)}].child[${e.currentTarget.dataset.item.parentKey}].kids[${e.currentTarget.dataset.item.key}].num`
      const fname = `rightmenu[${(e.currentTarget.dataset.item.grandparentKey)}].child[${e.currentTarget.dataset.item.parentKey}].num`
      this.setData({
        [name]: method === "add" ? num + 1 : num - 1,
        [fname]: this.data.rightmenu[(e.currentTarget.dataset.item.grandparentKey)].child[e.currentTarget.dataset.item.parentKey].num + (method === "add" ? 1 : -1)
      })
    },
    //跟后端套餐连接
    doCombo(e, method) {
      api.doCombo({
        data: {
          comboNo: e.currentTarget.dataset.item.itemNo,
          method: method,
          num: 1,
          name: e.currentTarget.dataset.item.descir,
          price: e.currentTarget.dataset.item.price + ""
        },
        success:()=>{
          this.doComboOrGuige(method, e)
        }
      })
    },
    //无掉进购物车动画的加法，主要针对的是购物车加减，特别是规格套餐要判断处理
    addmany_simple(e) {
      //三种情况
      if (e.currentTarget.dataset.item.guige === false && e.currentTarget.dataset.item.combo === true) {
        this.doCombo(e, "add")
      } else if (e.currentTarget.dataset.item.guige === true && e.currentTarget.dataset.item.combo === false) {
        this.addreduceShare({
          e: e,
          method: "add",
          callBack: (res, name, num) => {
            this.doComboOrGuige("add", e)
          }
        })
      } else {
        this.addreduceShare({
          e: e,
          method: "add",
          callBack: (res, name, num) => {
            this.setData({
              [name]: num + 1,
            })
          }
        })
      }
    },
    // 普通的加购物车包括动画
    debouce_addmany(e) {
      this.addreduceShare({
        e: e,
        method: "add",
        callBack: (res, name, num) => {
          this._throwlocation = {
            y: e.detail.y - 80,
            x: e.detail.x - 270
          }
          this.setData({
            throwimg: e.currentTarget.dataset.item.photoUrl,
          }, () => {
            this.throw()
            setTimeout(() => {
              this.setData({
                [name]: num + 1,
              })
            }, 400)
          })
        }
      })
    },
    //点击加号后的动画，其实就是把一个Img从图片位置收缩移到购物车的位置
    throw () {
      //先收缩，再移动，throwlocation是点击加号后被记录的加号旁边图片的动画
      this.animate("#throwid", [{
          top: this._throwlocation.y + "px",
          left: this._throwlocation.x + "px",
          height: "70px",
          width: "70px"
        },
        {
          top: this._throwlocation.y - 20 + "px",
          left: this._throwlocation.x - 20 + "px",
          height: "40px",
          width: "40px"
        },
      ], 200, () => {
        this.animate("#throwid", [{
            top: this._throwlocation.y - 20 + "px",
            left: this._throwlocation.x - 20 + "px",
            opacity: 1
          },
          {
            top: "850px",
            left: "50px",
            opacity: 0
          }
        ], 300, function () {
          this.clearAnimation("#throwid")
        }.bind(this))
      })
    },
    // 减就不说了
    jianmany(e) {
      if (e.currentTarget.dataset.item.guige === false && e.currentTarget.dataset.item.combo === true) {
        this.doCombo(e, "reduce")
      } else if (e.currentTarget.dataset.item.guige === true && e.currentTarget.dataset.item.combo === false) {
        this.doComboOrGuige("reduce", e)
        this.addreduceShare({
          e: e,
          method: "reduce",
          callBack: (res, name, num) => {

          }
        })
      } else {
        this.addreduceShare({
          e: e,
          method: "reduce",
          callBack: (res, name, num) => {
            this.setData({
              [name]: num - 1,
            })
          }
        })
      }
    },


    /*购物车系列方法*/
    // 展示购物车主要是面板的上移和遮罩的出现
    showcar() {
      if ((this.data.carcontentshow === false && this.data.thingnum != 0)) {
        this.animate('#car', [{
            opacity: 0.9,
            bottom: -300
          },
          {
            opacity: 1.0,
            bottom: 0
          },
        ], 90)
        this.animate('#zhezhao', [{
            opacity: 0
          },
          {
            opacity: 0.6
          }
        ], 90)
        this.setData({
          carcontentshow: true,
          bigscroll: false
        })

      } else {
        this.hiddcar()
      }
    },
    //清空购物车
    //因为点击清除要通知后端，而提交订单清除不需要，所以把公共部分提取出来
    clear() {
      for (let i = 0; i < this.data.rightmenu.length; i++) {
        for (let j = 0; j < this.data.rightmenu[i].child.length; j++) {
          if (this.data.rightmenu[i].child[j].num != 0) {
            let itemNum = `rightmenu[${i}].child[${j}].num`
            let itemKids = `rightmenu[${i}].child[${j}].kids`
            this.setData({
              [itemNum]: 0,
              [itemKids]: []
            })
          }
        }
      }
    },
    clearall({
      requestOrNO = true
    }) {
      if (requestOrNO) {
        api.clearShopCar({
          success: (res) => {
            this.clear()
          }
        })
      } else {
        this.clear()
      }
    },
    // 隐藏购物车
    hiddcar() {
      if (this.data.carcontentshow === true) {
        setTimeout(() => {
          this.setData({
            carcontentshow: false,
            bigscroll: true
          })
        }, 300)
        this.animate('#car', [{
            opacity: 1.0,
            bottom: 0
          },
          {
            opacity: 0.9,
            bottom: -300
          }
        ], 110)
        this.animate('#zhezhao', [{
            opacity: 0.6
          },
          {
            opacity: 0
          }
        ], 110)
      }
    },



    /*右菜单左菜单一一对应系列方法*/
    //这个方法主要是计算当前滑动的位置，并结合rightmenu每个类那几个字的top位置确定当前是哪个index左栏要变白，加了节流
    scrollthing(e) {
      // let time = this.activeTime || 0
      // if (Date.now() - time > 50) {
      // clearTimeout(this.timer);
      // this.timer = setTimeout(() => {
      let leftmenu = this.data.leftmenu
      let scrolltop = e.detail.scrollTop
      let indexkey = 0
      if (scrolltop < leftmenu[1].top - 20) {
        indexkey = 0
      } else if (scrolltop >= leftmenu[leftmenu.length - (this.data.ocupy+1)].top - 120) {
        indexkey = leftmenu.length -  (this.data.ocupy+1)
      } else {
        for (let i = 1; i < leftmenu.length -  1; i++) {
          if (scrolltop >= leftmenu[i].top - 20 && scrolltop < leftmenu[i + 1].top - 20) {
            indexkey = i
            break
          }
        }
      }
      this.setData({
        whiteIndex: indexkey,
        leftmenutop: (indexkey - 1) * 85
      })
      // this.activeTime = Date.now()
      // }
      // }, 100)
    },
    //当点击左菜单时可以把bigtop设为该item的top即为右菜单的top
    toscroll(e) {
      this.setData({
        bigtop: e.currentTarget.dataset.top
      })
    },


    //跳转到提交订单页面
    commitAll() {
      if (this.data.carthing.length !== 0) {
        wx.navigateTo({
          url: '../commit/commit',
          events: {
            // 为指定事件添加一个监听器，获取被打开页面传送到当前页面的数据
            clearall: (requestOrNO) => {
              this.clearall(requestOrNO)
            }
          },
          success: (res) => {
            // 通过eventChannel向被打开页面传送数据
            res.eventChannel.emit('acceptDataFromOpenerPage', {
              carthing: this.data.carthing,
              totalmuch: this.data.totalmoney,
              seat: app.globalData.state.seat
            })
          }
        })
      }
    },
    // 图片放大
    preview(event) {
      console.log(event.currentTarget.dataset.src)
      let currentUrl = event.currentTarget.dataset.src
      wx.previewImage({
        current: currentUrl, // 当前显示图片的http链
        urls: [currentUrl] // 需要预览的图片http链接列表
      })
    },

    // 节流
    throttle(func, wait) {
      let preTime = 0;
      return function () {
        let nowTime = +new Date();
        let context = this;
        let args = arguments;

        if (nowTime - preTime > wait) {
          func.apply(context, args);
          preTime = nowTime;
        }
      }
    },
  },

})